/*
 * AllVolunteersFrame.java
 */

package gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;

import exceptions.UPException;

import model.ListManager;
import model.User;

/**
 * JFrame to show a window containing a listing
 * of all Users and option buttons to blackball them.
 * 
 * @author Sean Brown
 * @version 1.0
 */
@SuppressWarnings("serial")
public class AllVolunteersFrame extends JFrame {

	/**
	 * The key to reference when finding ID values
	 * stored in components.
	 */
	private static final Object KEY = new Object();
	
	/**
	 * The ListManager for this run of the program.
	 */
	private final ListManager my_lm;
	
	/**
	 * Instantiates the frame.
	 * 
	 * @assumes the_lm is non-null.
	 * @param the_lm The ListManager.
	 */
	public AllVolunteersFrame(final ListManager the_lm) {
		super("All Volunteers");
		my_lm = the_lm;
	}
	
	/**
	 * Sets up all panels, preferences, and shows the frame
	 * on screen.
	 */
	public void start() {
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		UIManager.put("Panel.background", Color.WHITE);
		add(userPanel());
		pack();
		setSize(getSize().width, 500);
		setLocationRelativeTo(getRootPane());
		setVisible(true);
	}
	
	/**
	 * Returns a JPanel with the close button.
	 * 
	 * @return JPanel to display.
	 */
	private JPanel userPanel() {
		final JButton close = new JButton("Close");
		close.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e)
            {
                dispose();
            }
        });
		
		final JPanel button_panel = new JPanel(new FlowLayout());
		button_panel.add(close);

		final JScrollPane scroller = new JScrollPane
				(userButtonPanel(), JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
						JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		final JPanel user_panel = new JPanel(new BorderLayout());
		user_panel.add(scroller, BorderLayout.CENTER);
		user_panel.add(button_panel, BorderLayout.SOUTH);
		return user_panel;
	}
	
	/**
	 * Returns a JPanel that shows all Users and a button
	 * for each to blackball them.
	 * 
	 * @return JPanel to display.
	 */
	private JPanel userButtonPanel() {
		final int rows = my_lm.getVolunteers().size();
		final JPanel grid = new JPanel(new GridLayout(rows, 2));
		
		boolean user_exists = false;
		for (User u : my_lm.getVolunteers()) {
			final JTextArea name = new JTextArea(u.getName());
			name.setEditable(false);
			grid.add(name);
			final JButton bbbutton = BBButton(u.getID());
			if (u.isBlackballed()) {
				bbbutton.setEnabled(false);
			}
			grid.add(bbbutton);
			user_exists = true;
		}
		if (!user_exists) {
			final JTextArea no_users = new JTextArea("No Users Found.");
			no_users.setEditable(false);
			grid.add(no_users);
		}
		return grid;
	}
	
	/**
	 * Shows an error message when a User is determined
	 * already blackballed.
	 * 
	 * @assumes message is non-null.
	 * @param message The message to display in the error.
	 */
	private void blackballError(final String message) {
		GUIUtil.errorMessage(this, message);
	}

	/**
	 * Returns a Blackball JButton that has a property
	 * for the User ID it is associated with.
	 * 
	 * @param the_id The User ID to blackball when clicked.
	 * @return JButton object for blackballing a User.
	 */
	private JButton BBButton(final int the_id) {
		final JButton bbbutton = new JButton("Blackball");
		bbbutton.putClientProperty(KEY, the_id);
		bbbutton.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e)
            {
                final int id = ((Integer)((JButton)e.getSource()).
                		getClientProperty(KEY));
				try {
					User u = my_lm.findUser(id);
	                if (JOptionPane.showConfirmDialog(new JFrame(),
	                        "Are you sure you wish to blackball " + 
	                        		u.getName() + "?", "Confirm Blackball",
	                        JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
		                my_lm.blackballUser(u.getID());
		                //This should not happen.
		                if (!my_lm.findUser(id).isBlackballed()) {
		                	blackballError("Blackballing failed.");
		                } else {
		                	dispose();
			                new AllVolunteersFrame(my_lm).start();
		                }
	                }
				} catch (final UPException upe) {
					blackballError(upe.getMessage());
				}
            }
        });
		return bbbutton;
	}
}